%{
	#include <stdio.h>
	#include <stdlib.h>
	#include <string.h>
	#include "../tableSymbole/hashTable.h"
	#include "tableGencode.h"
	#include "tableValueText.h"
	#include "genMips.h"
	
	extern FILE* yyin;
	FILE* yyout;
	entree temporaire;
	char * bufferItoA;
	int erreurCompilation;
	int boolTemp;
%}

%token ENTIER PLUS FOIS PGAUCHE PDROITE IDENTIFIANT POINTVIRGULE AFFECTATION WRITE VAR DEUXPOINTS INT
%start debut
%left PLUS
%left FOIS
%left PGAUCHE

%%
debut : listdecla  listinstr
	;
listdecla : decla POINTVIRGULE listdecla
	|
	;
decla : VAR IDENTIFIANT DEUXPOINTS INT
		{
			ajoutEntreeHashTable(nouvelleEntreeCteInt(tableValueText[$2], 0));
			suppressionTableValueText($2);
		}
	;
listinstr : instr POINTVIRGULE listinstr
	|
	;
instr : IDENTIFIANT AFFECTATION	E
		{
			if(!existeMotClefHashTableHorsVide(tableValueText[$1]))
			{
				printf("Erreur : Yacc : identifiant non declare (%s).\n",tableValueText[$1]);
				erreurCompilation = 1;
			}
			else
			{
				bufferItoA = calloc (16, sizeof(char));
				sprintf(bufferItoA,"%d",$3);
				ajoutTableGencode("affectationVal",tableValueText[$1],bufferItoA,"");
			}
			
			suppressionTableValueText($1);
		}
	| IDENTIFIANT AFFECTATION IDENTIFIANT
		{
			boolTemp = 0;
			
			if(!existeMotClefHashTableHorsVide(tableValueText[$1]))
			{
				printf("Erreur : Yacc : identifiant non declare (%s).\n",tableValueText[$1]);
				erreurCompilation = 1;
				boolTemp = 1;
			}
			
			if(!existeMotClefHashTableHorsVide(tableValueText[$3]))
			{
				printf("Erreur : Yacc : identifiant non declare (%s).\n",tableValueText[$3]);
				erreurCompilation = 1;
				boolTemp = 1;
			}
			
			if(!boolTemp)
			{
				ajoutTableGencode("affectation",tableValueText[$1],tableValueText[$3],"");
			}
			
			suppressionTableValueText($1);
			suppressionTableValueText($3);
		}
	| WRITE IDENTIFIANT
		{
			if(!existeMotClefHashTableHorsVide(tableValueText[$1]))
			{
				printf("Erreur : Yacc : identifiant non declare (%s).\n",tableValueText[$1]);
				erreurCompilation = 1;
			}
			else
			{
				ajoutTableGencode("ecriture",tableValueText[$1],"","");
			}
				
			suppressionTableValueText($1);
		}
	| WRITE E
		{
			bufferItoA = calloc (16, sizeof(char));
			sprintf(bufferItoA,"%d",$1);
			ajoutTableGencode("ecritureVal",bufferItoA,"","");
		}
	;
	
E 	: E PLUS E 
		{
			$$ = $1 + $3;
		}
	| E FOIS E 
		{		
			$$ = $1 * $3;
		}
	| PGAUCHE E PDROITE 
		{
			$$ = $2;
		}
	| ENTIER 
		{
			$$ = $1;
		}
	;

	
%%

int yyerror(char * s)
{
	printf("\nErreur : %s\n\n", s);
	return -1;
}

int main (int argc, char ** argv)
{
	if(argc != 3)
	{
		printf("\nUsage : %s <nom fichier en entrée> <nom fichier en sortie>\n\n",argv[0]);
		exit(-1);
	}	
	
	if ((yyin = fopen(argv[1], "r")) == NULL)
	{                  
		printf("\nErreur : impossible d'ouvrir le fichier %s\n\n", argv[1]);
		exit(-1);
	}
	
	if ((yyout = fopen(argv[2], "w+")) == NULL)
	{
		printf("Erreur : impossible de créer le fichier %s\n", argv[2]);
		exit(-1);          
	}
	
	initVariableADeclarer();
	initTableGencode();
	initHashTable();
	initPiles();
	erreurCompilation = 0;
	
	printf("Debut analyse\n");
	yyparse();
	if(!hashTableVide())
	{
		sortieBloc();
	}
	printf("Fin analyse\n");
	
	afficheTableGencode();
	
	if(erreurCompilation)
	{
		printf("Erreur : Yacc : il y a eu des erreurs à la compilation.\n");
		exit(-1);
	}
		
	printf("Debut génération mips\n");
	mipsGeneration(yyout);
	printf("Fin génération mips\n");
	
	fclose(yyin);	
	fclose(yyout);
	
	return 0;
}
